`include "ctrl_encode_def.v"
module alu (A, B, ALUOp, C, Zero);
           
   input  [31:0] A, B;
   input  [4:0]  ALUOp;
   output [31:0] C;
   output Zero;
   
   reg [31:0] C;
   reg Zero;
          
   always @( A or B or ALUOp ) begin
      case ( ALUOp )
		 `ALUOp_NOP:  C = 0;
         `ALUOp_ADDU: C = A + B;
		 `ALUOp_ADD:  C = $signed(A) + $signed(B);
         `ALUOp_SUBU: C = A - B;
		 `ALUOp_SUB:  C = $signed(A) - $signed(B);
		 `ALUOp_AND:  C = A & B;
		 `ALUOp_OR:   C = A | B;
		 `ALUOp_NOR:  C = ~ (A | B);
		 `ALUOp_XOR:  C = A ^ B;
		 `ALUOp_SLT:  
		 begin
			if ($signed(A) < $signed(B))
				C = 1;
			else
				C = 0;
		 end
		 `ALUOp_SLTU:
		 begin
			if (A < B)
				C = 1;
			else
				C = 0;
		 end
		 
		 `ALUOp_EQL:
		 begin
		 	if (A == B)
		 		Zero = 1;
		 	else
		 		Zero = 0;
		 end
		 `ALUOp_BNE:
		 begin
		 	if (A == B)
		 		Zero = 0;
		 	else
		 		Zero = 1;
		 end

		 `ALUOp_SLL:  C = A << B[10:6];
		 `ALUOp_SRL:  C = A >> B[10:6];
		 `ALUOp_SRA:  C = ({32{A[31]}} << (32 - B[10:6])) | (A >> B[10:6]);
         
         default:   C = 0;
      endcase
   end // end always;


endmodule
    
